home *** CD-ROM | disk | FTP | other *** search
- R!SC's Solution to Duelist's Crackme #3 -- http://csir.cjb.net -- risc@notme.com :)
-
- Difficulty level : 5/10 (probably the toughest crack i have done)
-
- Tools Needed : Symantec Resource Workshop 1.0
- : W32Dasm
- : Hex WorkShop
- : Tasm
- : Softice
- : Efnet :) (optional)
-
-
- First off (well, after running the crackme, and trying a few random combinations), i loaded
- due-cm3.exe into W32Dasm, scrolling through the code, i soon found this bit...
-
- the important code...ESI points to button check order array thingy
-
- :00401127 0FBE8EFE204000 movsx ecx, byte ptr [esi+004020FE]
- :0040112E 83F94D cmp ecx, 0000004D <-- 4D is like a NULL terminator, also used
- :00401131 742F je 00401162 - for the last bit of maths
- :00401133 890D5E214000 mov dword ptr [0040215E], ecx <-- save the current button iD
- :00401139 51 push ecx <-- button iD
- :0040113A FF7508 push [ebp+08] <-- dialog box handle
-
- * Reference To: USER32.IsDlgButtonChecked, Ord:0000h
- |
- :0040113D E8D0010000 Call 00401312
- :00401142 46 inc esi <-- Counter, points to next button,
- :00401143 83F800 cmp eax, 00000000 - and used in the maths
- :00401146 74DF je 00401127 <-- Loop until one is found checked...
- :00401148 A15E214000 mov eax, dword ptr [0040215E] <-- Our checked box iD
- :0040114D 0FBE8EFE204000 movsx ecx, byte ptr [esi+004020FE] <-- Next button iD
- :00401154 0FAFC1 imul eax, ecx <-- Multiply next button iD with current one
- :00401157 0FAFC6 imul eax, esi <-- Multiply count with answer
- :0040115A 010562214000 add dword ptr [00402162], eax <-- Add it to our magic number
- :00401160 EBC5 jmp 00401127
-
- * Referenced by a (U)nconditional or (C)onditional Jump at Address:
- |:00401131(C)
- |
- :00401162 A162214000 mov eax, dword ptr [00402162] <-- Our final magic number..
- :00401167 6BC04D imul eax, 0000004D
- :0040116A 3D6654F300 cmp eax, 00F35466 <-- Magic number we have to get...
-
-
- So, from this, we know we can bpx IsDlgButtonChecked, to make softice break at the routine
- which does the checking. After returning from USER32.IsDlgButtonChecked, if eax is NULL, the
- button wasnt checked, and it loops back to get the next iD, if eax != 0, the button is
- checked, and it does some maths on it
-
- MAGIC NUMBER = MAGIC NUMBER + (Current box iD * Next box iD * Button counter)
-
- After the last button, it puts our MAGIC NUMBER into eax, multiplys it by 4D, then compares
- it against the predifined number we have to get, F35466.. for the sake of it, to save some
- maths, F35466 / 4D = 328FE (the number i finally use to figure out the correct order of ticks)
-
- At the start of the routine, it loads ESI with the check order of the buttons, displaying the
- memory at [esi+004020FE] (when ESI==0) we get this information
-
- ---button iD check order---
-
- 004020FE 16 49 5E 15 27 26 21 25 1D 59 53 37 31 48 5D 0C 61 52 4D
- ESI== 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 --
- my id 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 (9*2)
-
- This means bugger all to us, because we dont know which number represents which check box on
- the screen. We have to use a resource editor, to look at the dialog box resources, and find out
- which box uses which iD..
-
- I used Symantec Resource Editor 1.0, availble from http:\\protools.cjb.net (couldnt get BRW to
- load the exe) . So load due-cm3.exe into your resource editor, and click to edit the dialog...
- After clicking on each button, starting from the top left, converting the iD into hex, then
- writing them down, i got this information from it..
-
- Buttons on screen
- 61 49 5E 16 25 26 21 59 53 ; top row of check boxes
-
- 15 37 31 48 5D 0C 52 27 1D ; bottom row of check boxes 10-18
-
- Okay, with all this information, we know what button gets checked when, and we still cant figure
- out the correct order (can you do the maths in your head?)
-
- My theory, to write a brute forcer, which will go through every possible combination you can
- have, do the maths on them, and compare the result with 328FE (the correct MAGIC NUMBER / 4D)
-
- 90 minutes of coding later (i am real bad at this :) i got a result!!
-
- Picture this in your head, 18 boxes, can be checked or unchecked, 0 or 1, imagine a binary
- value, using 18 bits, to represent these boxes, we test each bit in the binary value, if its
- 0 it represents an unchecked box, if its 1, it represents a tick ;) we use a 1 bit binary value,
- scrolling this to the left, bit by bit, and increase a counter, so we know which bit we are
- checking (bit 0 through to 17), test a with b, if the bit is set, do the maths..
-
- (see the comments i added to the source for the brute forcer..)
-
- theory behind R!SC's Matrix Brute Forcer (r)
-
- we have 18 check boxes, can be either 'checked' or 'unchecked' (1 or 0)
- apparantly, the amount of diff combo's is square of 18, 324???
- so where i come up with 262,144 :)
-
- we also have a way of testing single 'bits' in a value, by using 'TEST dest, src'
- i use a 18bit binary value (well, 32bit binary value, but only use the TEST on the first
- 18 bits of it...) (i'll refer to this as my MAGIC NUMBER)
-
- i start the MAGIC NUMBER with the first bit set, (01h) then do the maths, check the result,
- if it doesnt find the correct answer, we increase the MAGIC NUMBER by 1, and check again....
-
- examples of the MAGIC NUMBER, and how it represents the matrix of check boxes....
-
- 000000000000000001 = 01h = box 1 checked, 2-18 unckecked, simulate the maths, check the results
- 000000000000000010 = 02h = box 2 checked, 1,3-18 unchecked
- 000000000000000011 = 03h = box 1,2 checked, 3-18 unckecked
- 000000000000000100 = 04h = box 3 checked, 1,2,4-18 unchecked
- 000000000000000101
- 000000000000000110
- 000000000000000111 = 07h = box 1-3 checked, 4-18 unchecked...
- 000000000000001000
- 000000000000001001
-
- 101000110101000110 = 028d46h = box 2,3,7,9,11,12,16,18 checked
- box 1,4,5,6,8,10,13,14,15,17 unchecked
- 111111111111111111 = 03ffffh = box 1-18 checked...
-
- to find out if a bit is set or not, i use another 18bit (32bit :) value, with only one bit
- set in it (i'll call this X)
-
- TEST MAGIC NUMBER, X ; see if bit 'X' is set in the magic number
- JNZ CHECKED ; if bit 'X' is not '0' jump to calculation routine
-
- which will check bit X in the MAGIC NUMBER, and alter the ZERO flag accordingly
- i.e, bit X is 0, zero flag is set, bit X is 1, zero flag is cleared...
-
- X gets shifted to the left by 1 bit, the counter increased, check the counter, if its equal
- to 18, we have checked every bit in the MAGIC NUMBER, and have to loop back to check our result
- erm... still with me??
-
- examples of X
-
- 000000000000000001 = bit 1 set = 01h, counter = 0
- 000000000000000010 = bit 2 set = 02h, counter = 1
- 000000000000000100 = bit 3 set = 04h, counter = 2
- 000000000000001000 = bit 4 set = 08h, counter = 3
- 000000000000010000 = bit 5 set = 10h, counter = 4
- 000000000000100000 = bit 6 set = 20h, counter = 5
- 000000000001000000 = bit 7 set = 40h, counter = 6
- ..................
- 001000000000000000 = bit 16 set = 08000h, counter = 15
- 010000000000000000 = bit 17 set = 10000h, counter = 16
- 100000000000000000 = bit 18 set = 20000h, counter = 17
- bit gets shifted one more time, counter increased to 18,
- counter gets checked, weve done, so loop back and check the answer...
-
- okay, go study the source code
- ...
- ...
- heh, you back already? try changing this line
-
- :0040116A 3D6654F300 cmp eax, 00F35466
-
- to read
-
- :0040116A 3D6E8BC000 cmp eax, 00C08B6E ; file offset 76A
-
- and figure out the correct sequence :)
-
- (CHANGE ALREADY MADE IN 28026-DUE-CM3.EXE)
- (SOLUTION IN TEST.ZIP)
-
- R!SC 31st May 1999
-
-
-